Skip to content

fix: pass arrow keys through in normal and visual mode - #66

Merged
oribarilan merged 1 commit into
mainfrom
fix/arrow-keys-passthrough
Sep 2, 2026
Merged

fix: pass arrow keys through in normal and visual mode#66
oribarilan merged 1 commit into
mainfrom
fix/arrow-keys-passthrough

Conversation

@oribarilan

Copy link
Copy Markdown
Owner

What

In normal and visual mode, arrow keys (up/down/left/right) now pass through to OpenCode instead of being swallowed by the vim intercept.

Why

handleNormalKey and handleVisualKey end with a catch-all that consumes any unbound key. Arrow keys aren't vim motions (only hjkl are), so they hit that catch-all and were consumed with no action. The intercept then called ctx.consume(), so OpenCode never saw the key.

That trapped users in the subagent view (#63): after pressing Esc to enter normal mode, arrow_up did nothing, and the only way out was the non-obvious workaround of pressing i to re-enter insert mode (where arrows already passed through).

How

Return PASS for up/down/left/right in both handlers, before the catch-all. Insert mode already passed them through, so behavior is now consistent across modes. In the prompt they do the host's default (move the cursor); in views like the subagent view they drive native navigation.

Note: in visual mode arrows move the cursor via the host rather than extending the selection like hjkl. That keeps the fix simple and avoids trapping keys. Extending selection on arrows can be a follow-up.

Tests

  • Unit (TDD, red first): 4 directions x normal + visual = 8 tests asserting the handlers return PASS (not consumed, no actions).
  • Integration: drives the real pipeline (plugin.tui to the key intercept) and asserts the intercept does not consume arrows, with a control that a vim motion (j) still is.

just check is green (222 tests).

Fixes #63

handleNormalKey and handleVisualKey ended with a catch-all that consumes
any unbound key. Arrow keys aren't vim motions (only hjkl are), so they
hit that catch-all and were swallowed, and the intercept then called
ctx.consume(), so OpenCode never received the key.

In the subagent view that trapped users (issue #63): after Esc to enter
normal mode, arrow_up did nothing, and the only way out was the
non-obvious workaround of pressing i to re-enter insert mode, where
arrows already passed through.

Return PASS for up/down/left/right in both handlers so the host handles
them (move the cursor in the prompt, exit the subagent view, etc.), now
consistent with insert mode. In visual mode arrows move the cursor via
the host rather than extending the selection; extending on arrows can be
a follow-up.

Fixes #63
@oribarilan
oribarilan merged commit fdf8d83 into main Sep 2, 2026
1 check passed
@oribarilan
oribarilan deleted the fix/arrow-keys-passthrough branch September 2, 2026 06:27
oribarilan added a commit that referenced this pull request Sep 2, 2026
Patch release for the #63 fix (already merged via #66).

### Fixed

- Arrow keys no longer get swallowed in normal and visual mode. They
pass through to OpenCode, so you can exit the subagent view (and use
other native navigation) without first switching to insert mode
([#63](#63)).

### Release checklist

- [x] Moved `[Unreleased]` into `## [0.17.1]` and updated CHANGELOG link
refs
- [x] Bumped `package.json` to 0.17.1
- [x] Bumped `VERSION` in `src/version.ts` to match
- [x] Updated README install/config version tags to v0.17.1
- [x] `just check` green (222 tests)

Tag `v0.17.1` and the GitHub release follow after this merges.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

How to exit subagent view?

1 participant